﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;
using System.Net;
using System.IO;
using System.Net.Cache;

namespace Proxy3
{
    public partial class Form1 : Form
    {
        public static class Status
        {

            static public Form1 form;

            public static string proxyString;
            public static int proxySpeed = 0;

            private static void fresh()
            {
                form.toolStripStatusLabel1.Text = proxyString;
                form.toolStripStatusLabel2.Text = "speed:" + proxySpeed.ToString();
            }

            public static void setProxy(string proxyStr)
            {
                proxyString = proxyStr;
                fresh();
            }
            public static void setSpeed(int speed)
            {
                proxySpeed = speed;
                fresh();
            }
        }

        // Global

        Utility engine = new Utility();

        List<ProxyInfoArgs> proxys = new List<ProxyInfoArgs>();

        List<ProxyInfoArgs> sortedProxys = new List<ProxyInfoArgs>();


        #region Windows

        AboutBox1 aboutBox1;
        Wifi wifi1;

        #endregion

        #region Utility

        // Download Proxy List
        private void LoadProxyInfo()
        {
            var proxyRst = engine.GetProxyInfo();
            if (proxyRst == null)
            {
                button5.Enabled = false;
                return;
            }
            foreach (var proxy in proxyRst)
            {
                proxys.Add(new ProxyInfoArgs(proxy, 0));
            }
        }

        // Test All Proxy
        SubThread[] thread;
        private void TestAllProxys()
        {
            if (proxys.Count == 0)
                return;

            sortedProxys = new List<ProxyInfoArgs>();
            listBox1.Items.Clear();
            listBox2.Items.Clear();

            thread = new SubThread[proxys.Count];
            for (int i = 0; i < proxys.Count; i++)
            {
                thread[i] = new SubThread(proxys[i].Proxy);
                thread[i].MessageSend += new SubThread.MessageEventHandler(_subthread_MessageSend);
                thread[i].StartThread();
            }

        }

        /// <summary>
        /// 深度测试当前代理是否可用
        /// </summary>
        /// <returns></returns>
        private string TestCurrentProxy()
        {
            System.Threading.Thread.Sleep(1000);
            try
            {
                //webBrowser1.Navigate("http://chong.b3log.org/software/proxy.htm");
                //while (webBrowser1.ReadyState != WebBrowserReadyState.Complete)
                //{
                //    Application.DoEvents();
                //}

                // No Cache Policy
                HttpRequestCachePolicy policy = new HttpRequestCachePolicy(HttpRequestCacheLevel.Default);
                HttpWebRequest.DefaultCachePolicy = policy;

                var request = (HttpWebRequest)HttpWebRequest.Create("http://chong.b3log.org/software/proxy.htm");

                HttpRequestCachePolicy noCachePolicy = new HttpRequestCachePolicy(HttpRequestCacheLevel.NoCacheNoStore);
                request.CachePolicy = noCachePolicy;

                // Trivial Settings
                request.Accept = "*/*";
                request.UserAgent = "Mozilla/4.0 (MSIE 6.0; Windows NT 8982 )";
                request.Headers["Accept-Language"] = "zh-cn";
                request.Timeout = 12000;

                HttpWebResponse oWebResp = (HttpWebResponse)request.GetResponse();
                StreamReader oStream = new StreamReader(oWebResp.GetResponseStream(), System.Text.Encoding.GetEncoding("UTF-8"));
                string sResp = oStream.ReadToEnd();

                //                webBrowser1.Document.Body.InnerHtml = sResp;
                webBrowser1.Navigate("about:blank");
                webBrowser1.Document.Write(sResp);
                webBrowser1.Refresh();

                string extraInfo;
                // Get Extra Info
                var list = webBrowser1.Document.GetElementById("info");
                if (list == null)
                {
                    extraInfo = "error";
                }
                else
                {
                    extraInfo = list.InnerHtml;
                }
                return extraInfo;
            }
            catch
            {
                return "error";
            }
        }


        private void ChangeProxyAuto(bool promp = true)
        {
            int ind = 0;

            do
            {
                //修改代理
                if (ind >= listBox1.Items.Count)
                {
                    MessageBox.Show("由于网络原因，请稍后再试");
                    return;
                }
                listBox1.SelectedIndex = ind;
                string proxyStr = "http://" + listBox1.SelectedItem.ToString();

                Status.setProxy(proxyStr);

                SetIEProxy(Status.proxyString);

                Status.setSpeed(sortedProxys[ind].Speed);

                ind++;
            }
            while (TestCurrentProxy() == "error");
            if ( promp )
                MessageBox.Show(TestCurrentProxy(), "Enjoy!");
        }

        /// <summary>
        /// 更改IE设置
        /// </summary>
        /// <param name="proxy"></param>
        private void SetIEProxy(string proxy)
        {
            ProcessStartInfo info = new ProcessStartInfo();
            info.FileName = "proxyConsole.exe";
            info.WindowStyle = ProcessWindowStyle.Hidden;
            info.Arguments = proxy;

            Process proc;
            proc = Process.Start(info);
        }

        /// <summary>
        /// 撤销IE设置
        /// </summary>
        private void ResetIEProxy()
        {
            ProcessStartInfo info = new ProcessStartInfo();
            info.FileName = "proxyConsole.exe";
            info.WindowStyle = ProcessWindowStyle.Hidden;
            info.Arguments = "clear";

            Process proc;
            proc = Process.Start(info);
        }

        #endregion

        #region Multi-Threading   and   Message Utility

        public delegate void MessageHandler(ProxyInfoArgs e);

        private void _subthread_MessageSend(object sender, ProxyInfoArgs e)
        {
            try
            {
                MessageHandler handler = new MessageHandler(Message);
                this.Invoke(handler, new object[] { e });
            }
            catch { }
        }

        public void Message(ProxyInfoArgs e)
        {
            if (sortedProxys.Count == 0)
            {
                sortedProxys.Add(e);
                listBox1.Items.Add(e.Proxy);
                listBox2.Items.Add(e.Proxy + "Speed:" + e.Speed.ToString());

                for ( int i =0; i < proxys.Count; i ++ )
                    if (e.Proxy.Contains(proxys[i].Proxy))
                    {
                        proxys[i].Speed = e.Speed;
                    }

                return;
            }
            for (int i = 0; i <= sortedProxys.Count; i++)
            {
                if (sortedProxys[i].Speed < e.Speed)
                {
                    sortedProxys.Insert(i, e);
                    listBox1.Items.Insert(i, e.Proxy);
                    listBox2.Items.Insert(i, e.Proxy + "Speed:" + e.Speed.ToString());
                    break;
                }

            }

            //listBox1.Items.Clear();
            //listBox2.Items.Clear();
            //foreach (var item in sortedProxys)
            //{
            //    listBox1.Items.Add(item.Proxy);
            //    listBox2.Items.Add(item.Proxy + item.Speed.ToString());
            //}
        }

        #endregion


        #region Form Events

        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            TestAllProxys();
        }

        private void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
        {

        }

        private void Form1_Load(object sender, EventArgs e)
        {
            Application.DoEvents();

//            LoadProxyInfo();
            Status.form = this;

//            TestAllProxys();
        }

        private void button2_Click(object sender, EventArgs e)
        {
            if (listBox1.SelectedItem == null)
                listBox1.SelectedItem = listBox1.Items[0];

            //修改代理
            int proxyInd = listBox1.SelectedIndex;
            string proxyStr = "http://" + listBox1.SelectedItem.ToString();

            Status.setProxy(proxyStr);

            SetIEProxy(Status.proxyString);

            Status.setSpeed(proxys[proxyInd].Speed);

            string testRst = TestCurrentProxy();
            if (testRst == "error")
            {
                MessageBox.Show("代理不可用，请更换");
            }
            else if (testRst == "OK ")
            {
                MessageBox.Show("代理可用，Enjoy!!");
            }
            else
            {
                MessageBox.Show("代理可用，Engoy!!");
                MessageBox.Show(testRst);
            }
        }

        private void button4_Click(object sender, EventArgs e)
        {

        }

        private void webBrowser1_DocumentCompleted_1(object sender, WebBrowserDocumentCompletedEventArgs e)
        {

        }

        private void button5_Click(object sender, EventArgs e)
        {
            Application.UseWaitCursor = true;
            ChangeProxyAuto();
            Application.UseWaitCursor = false;
        }

        private void button3_Click(object sender, EventArgs e)
        {
            ResetIEProxy();
        }


        protected override void OnClosed(EventArgs e)
        {
            base.OnClosed(e);
            Application.Exit();
        }

        #endregion

        private void 退出ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            foreach (var item in thread)
            {
		        item.EndThread();
            }
            //Application.ExitThread();
            Application.Exit();
//            Application.Exit(new CancelEventArgs(false));
        }

        private void 版权信息ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            aboutBox1 = new AboutBox1();
            aboutBox1.Show();
        }

        private void 帮助ToolStripMenuItem1_Click(object sender, EventArgs e)
        {
            MessageBox.Show("使用很简单\n只需点击最大的那个按钮\n出现问题请访问作者博客并留言");
        }

        private void 更新ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            engine.GetUpdateInfo();
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            if (持续更换代理ToolStripMenuItem.Checked)
            {
                Application.UseWaitCursor = true;
                ChangeProxyAuto(false);
                Application.UseWaitCursor = false;
            }
        }

        private void 持续更换代理ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            持续更换代理ToolStripMenuItem.Checked = !持续更换代理ToolStripMenuItem.Checked;
        }


        int phase = 0;
        private void initPhase_Tick(object sender, EventArgs e)
        {
            switch (phase)
            {
                case 0:
                    phase = 1;
                    ResetIEProxy();
                    break;
                case 1:
                    phase = 2;
                    LoadProxyInfo();
                    TestAllProxys();
                    break;
            }
        }

        private void wifiToolStripMenuItem_Click(object sender, EventArgs e)
        {
            wifi1 = new Wifi();
            wifi1.Show();
        }

    }
}
